package com.gykj.admin.config;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import redis.clients.jedis.exceptions.JedisConnectionException;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;

/**
 * @ClassName: MybatisCache
 * @Description: TODO 使用第三方内存数据库Redis作为二级缓存
 * @author lmx.
 * @date
 */
public class MybatisCache implements Cache  {
	private static final Logger logger = LoggerFactory.getLogger(MybatisCache.class);
	
//	private static final String MYBATIS_REDIS_CACHE = "mybatis_redis_cache:";
	
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	// cache instance id
	private final String id; 
	//缓存模板
	private static RedisTemplate<String, Object> redisTemplate;
	
	public MybatisCache(String id) {
		if (id == null) {
			throw new IllegalArgumentException("Cache instances require an ID");
		}
		this.id = id;
	}

	@Override
	public String getId() {
		return id;
	}

	/**
	 * Put query result to redis
	 * @param key
	 * @param value
	 */
	@Override
	public void putObject(Object key, Object value) {
		RedisConnection connection = null;
		try {
			connection = redisTemplate.getConnectionFactory().getConnection();
			if (null == connection) {
				logger.error(MybatisCache.class.getName()+" Redis Connection is null");
				
			}
			if (null == value) {
				logger.error(MybatisCache.class.getName()+" value is null");
				return ;
			}
			
/*			RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
			connection.set(serializer.serialize(key),serializer.serialize(value));*/
			
/*			RedisSerializer<Object> serializer = new EntityRedisSerializer();
			connection.set(serializer.serialize(key),serializer.serialize(value));*/
			
			RedisSerializer<Object> serializer =  new GenericFastJsonRedisSerializer();
//			connection.set(serializer.serialize(key),serializer.serialize(value));
			connection.set(new StringRedisSerializer().serialize(key.toString()),serializer.serialize(value));
			
		} catch (JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
		logger.debug("Put query result to redis");
	}

	/**
	 * Get cached query result from redis
	 * @param key
	 * @return
	 */
	@Override
	public Object getObject(Object key) {
		Object result = null;
		RedisConnection connection = null;
		try {
			connection = redisTemplate.getConnectionFactory().getConnection();
			if (null == connection) {
				logger.error(MybatisCache.class.getName()+" Redis Connection is null");
				
				
			}
			if (null == key) {
				logger.error(MybatisCache.class.getName()+" key is null");
			}
			
			connection = redisTemplate.getConnectionFactory().getConnection();
			
/*			RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
			result = serializer.deserialize(connection.get(serializer.serialize(key)));*/
			
/*			RedisSerializer<Object> serializer = new EntityRedisSerializer();
			result = serializer.deserialize(connection.get(serializer.serialize(key)));*/
			
			RedisSerializer<Object> serializer = new GenericFastJsonRedisSerializer();
//			result = serializer.deserialize(connection.get(serializer.serialize(key)));
			result = serializer.deserialize(connection.get(new StringRedisSerializer().serialize(key.toString())));
			
		} catch (JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
		logger.debug("Get cached query result from redis");
		return result;
	}

	/**
	 * Remove cached query result from redis
	 * @param key
	 * @return
	 */
	@Override
	public Object removeObject(Object key) {
		redisTemplate.delete(key.toString());
		logger.debug("Remove cached query result from redis");
		return null;
	}

	/**
	 * Clears this cache instance
	 */
	@Override
	public void clear() {
		RedisConnection connection = null;
		try {
			connection = redisTemplate.getConnectionFactory().getConnection();
			connection.flushDb();
			connection.flushAll();
		} catch (JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
		logger.debug("Clear all the cached query result from redis");
	}

	@Override
	public int getSize() {
		return 0;
	}

	@Override
	public ReadWriteLock getReadWriteLock() {
		return readWriteLock;
	}

	public static void setRedisTemplate(RedisTemplate<String, Object> template) {
		if (null == redisTemplate) {
			redisTemplate = template;
		}
	}
}
